package bman.tools.net;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.InputStream;
import java.net.Socket;
import java.util.logging.Logger;

/**
 * This is a component used by of the Radio class. Don't bother much with this.
 * 
 * This class listens for incoming messages and calls the Receiver associated with the
 * instance of this class. 
 * 
 * Message Protocol is: <message_length>+<message>
 * 
 * The message is read as follows. First the message length is read from the socket. Then
 * bytes corresponding to that length is read.
 * 
 * @author MrJacky
 *
 */
public class SocketListener extends Thread 
{
	Logger log = Logger.getLogger(SocketListener.class.getName());
	
	
	Socket m_socket;
	Receiver m_Receiver;
	
	boolean run = true;
	
	int errorCount = 0;
	
	String address = "UNASSIGNED";
	
	public SocketListener(Socket socket, Receiver Receiver)
	{
		m_socket = socket;
		m_Receiver = Receiver;
		
		address = m_socket.getInetAddress().getHostName()+":"+m_socket.getLocalPort();
		start();
	}
	
	public void messageRecieved(byte[] message)
	{
		try
		{
			m_Receiver.receive(m_socket, message);
			log.fine("Message received: "+new String(message));
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	
	public void run()
	{
		
		InputStream is = null;
		DataInputStream di = null;
		BufferedInputStream bio = null;
		try
		{
			is = m_socket.getInputStream();
			bio = new BufferedInputStream(is);
			di = new DataInputStream(bio);
		}
		catch(Exception e)
		{
			run = false;
			e.printStackTrace();
			log.severe("Unable to start SocketListener. Exception message is: "+e.getLocalizedMessage());
		}
		
		long total = 0;
		
		while(run)
		{
			try
			{
				int message_length = di.readInt();
				
				log.fine("Message recieved, going to read "+message_length+" bytes from connection");
				long start = System.currentTimeMillis();
		
				byte[] b = new byte[message_length];
				
				di.read(b);
				
				total += System.currentTimeMillis() - start;
				log.fine("Total Time to Read: "+total+"ms");
				messageRecieved(b);
				
				errorCount = 0;
				
			}
			catch(Exception e)
			{
				errorCount++;
				log.warning("Error reading from socket. Error message is: "+e.getMessage());
				e.printStackTrace();
				
				if(errorCount > 3)
				{
					run = false;
					log.severe("There are too many errors in this connection. Stopping SocketListener");
				}
			}
		}
	}
}
